/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package it.coraci.anag.gui.components.basic.gui;

import it.coraci.anag.db.mongo.entities.Attribute;
import it.coraci.anag.db.sql.entities.Person;
import it.coraci.anag.gui.components.basic.annotations.GuiParam;
import it.coraci.anag.gui.components.basic.annotations.GuiParamBooleanValue;
import it.coraci.anag.gui.components.basic.annotations.GuiParamMultiValue;
import it.coraci.anag.gui.components.basic.gui.logic.CRUDCentral;
import it.coraci.anag.gui.components.basic.gui.logic.CRUDParametrizablePanel;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

/**
 *
 * @author Luca
 */
public class AddNewEntityFrame extends javax.swing.JFrame {

    private Class<?> clazzToSave;
    private boolean editable = false;
     private Object currentEntity = null;
    private Map<String, CRUDParametrizablePanel> keyPanel = new HashMap<String, CRUDParametrizablePanel>();

    /**
     * Creates new form AddNewEntityFrame
     */
    public AddNewEntityFrame(Class<?> clazzToSave) {

        initComponents();
        this.clazzToSave = clazzToSave;
        this.editable = true;
        prepareForClass(clazzToSave);

    }

       public final void prepareForClass(Class<?> clazz) {
        System.out.println("analizing: " + clazz.getCanonicalName());
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            System.out.println("field: " + field.getName());
            field.setAccessible(true);
            Annotation[] declaredAnnotations = field.getDeclaredAnnotations();
            for (Annotation annotation : declaredAnnotations) {
                if (annotation instanceof GuiParam) {
                    GuiParam gp = field.getAnnotation(GuiParam.class);
                    Attribute attr = new Attribute(gp.label(), null);
                    CRUDParametrizablePanel panel = null;
                    switch (gp.type()) {
                        case TEXT:
                            panel = new SimpleTextParamPanel(attr);
                            jPanel_new.add((JPanel) panel);
                            break;
                        case BOOLEAN:
                            if (field.getAnnotation(GuiParamBooleanValue.class) != null) {
                                GuiParamBooleanValue guiParamBooleanValue = field.getAnnotation(GuiParamBooleanValue.class);
                                panel = new SimpleBooleanMultiParamPanel(attr, guiParamBooleanValue.trueValue(), guiParamBooleanValue.falseValue());
                            } else if (field.getAnnotation(GuiParamMultiValue.class) != null) {
                                GuiParamMultiValue gg = field.getAnnotation(GuiParamMultiValue.class);
                                panel = new SimpleMultiParamPanel(attr, gg.multivalues());
                            } else {
                                System.out.println(" ---- no anno");
                                panel = new SimpleBooleanParamPanel(attr);
                            }
                            jPanel_new.add((JPanel) panel);
                            break;
                        case DATE:
                            panel = new SimpleDateParamPanel(attr);
                            jPanel_new.add((JPanel) panel);
                            break;
                            case ONE_TO_MANY:
                                System.out.println("FIELD : "+field.getName());
//                                panel = new SimpleOneToManyParamPanel(gp.label(), ((List<Object>) field.get(currentEntity)).toArray());
                            panel = new SimpleOneToManyParamPanel(gp.label(), new Object[]{});
                            ParameterizedType stringListType = (ParameterizedType) field.getGenericType();
                            Class<?> newClazzType = (Class<?>) stringListType.getActualTypeArguments()[0];
                            ((SimpleOneToManyParamPanel)panel).setNewEntityClazz(newClazzType);
                            ((SimpleOneToManyParamPanel)panel).setParentObject(currentEntity);
                            ((SimpleOneToManyParamPanel)panel).setListFieldName(field.getName());
                            jPanel_new.add((JPanel) panel);
                            break;
                        case ONE_TO_ONE:
                            System.out.println("FIELD : " + field.getName());
                            List<?> entities = CRUDCentral.getInstance().findAllEntities(field.getType());
                            
                            panel = new SimpleOneToOneParamPanel(gp.label(), entities.toArray());
//                            ParameterizedType stringListType = (ParameterizedType) field.getGenericType();
//                            Class<?> newClazzType = (Class<?>) stringListType.getActualTypeArguments()[0];
                            ((SimpleOneToOneParamPanel) panel).setNewEntityClazz(field.getType());
//                            ((SimpleOneToManyParamPanel) panel).setParentObject(currentEntity);
//                            ((SimpleOneToManyParamPanel) panel).setListFieldName(field.getName());
                            jPanel_new.add((JPanel) panel);
                            break;
                    }
                    if (panel != null) {
                        this.keyPanel.put(field.getName(), panel);
                        panel.setEditable(editable);
                    }
                } else if (annotation instanceof GuiParamBooleanValue) {
                    System.out.println("  ------- ABABUAHUSHduahsdu");
                }
            }

        }
    }

    public void setCurrentEntity(Object currentEntity) {
        this.currentEntity = currentEntity;
    }
    

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jPanel_new = new javax.swing.JPanel();
        jButton1 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

        jPanel_new.setLayout(new javax.swing.BoxLayout(jPanel_new, javax.swing.BoxLayout.Y_AXIS));

        jButton1.setText("Save");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel_new, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap(333, Short.MAX_VALUE)
                .addComponent(jButton1)
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addComponent(jPanel_new, javax.swing.GroupLayout.DEFAULT_SIZE, 332, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jButton1)
                .addContainerGap())
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        try {
            System.out.println("-------------- REFLECTION ---------------");
            Object entity = this.clazzToSave.getConstructor().newInstance();
            for (String fieldName : this.keyPanel.keySet()) {
                Field declaredField = entity.getClass().getDeclaredField(fieldName);
                declaredField.setAccessible(true);
                if (keyPanel.get(fieldName).getValue() != null) {
                    declaredField.set(entity, keyPanel.get(fieldName).getValue());
                }else{
//                    System.out.println("field: "+);
                }
            }
            CRUDCentral.getInstance().saveEntity(entity);
            JOptionPane.showMessageDialog(null, "New Entity has been correctly stored");
            this.setVisible(false);
            this.dispose();
        } catch (NoSuchMethodException ex) {
            Logger.getLogger(AddNewEntityFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(AddNewEntityFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            Logger.getLogger(AddNewEntityFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(AddNewEntityFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalArgumentException ex) {
            Logger.getLogger(AddNewEntityFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(AddNewEntityFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NoSuchFieldException ex) {
            Logger.getLogger(AddNewEntityFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
    }//GEN-LAST:event_jButton1ActionPerformed


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel_new;
    // End of variables declaration//GEN-END:variables
}
